
package com.idealighter.game.games.fqzs.manager;

import com.alibaba.fastjson.TypeReference;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.idealighter.game.core.common.Game;
import com.idealighter.game.core.tuple.Pair;
import com.idealighter.game.dictionary.dic.SharkIconRateDic;
import com.idealighter.game.dictionary.domain.SharkIconRateDomain;
import com.idealighter.game.games.fqzs.struct.SharkSeat;
import com.idealighter.game.games.fqzs.struct.SharkTable;
import com.idealighter.game.prizepool.manager.RoomPrizePoolMgrScript;
import com.idealighter.game.prizepool.struct.control.SharkControl;
import com.idealighter.game.prizepool.struct.room.ControlStrategy;
import com.idealighter.game.prizepool.struct.room.RoomPrizePool;
import com.idealighter.utils.code.RandCodeUtil;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 飞禽走兽控制 .
 * 
 * @date 2016年2月20日 上午10:05:09
 *
 */
@Singleton
public class SharkControlScript {

  @Inject
  private RoomPrizePoolMgrScript roomPrizePoolMgr;
  @Inject
  private SharkIconRateDic iconRateDic;
  @Inject
  private SharkMgr sharkMgr;

  private static final TypeReference<SharkControl> SHARK_CONTROL_TYPE_REFERENCE =
      new TypeReference<SharkControl>() {};

  private static Map<Integer, Integer> count = new HashMap<Integer, Integer>();

  /**
   * 控制随机奖励图标,只控制房间奖池 .
   * 
   * @param table .
   */
  public Integer controlRandomRewardIcon(SharkTable table) {
    RoomPrizePool roomPrizePool =
        roomPrizePoolMgr.defaultRoomPrizePool(Game.FQZS, table.getRoom().getId());
    if (roomPrizePool != null) {
      ControlStrategy strategy = roomPrizePool.abledControlStrategy();
      // 系统输赢
      boolean sysWin = RandCodeUtil.randomBoolean();

      if (strategy != null) {
        SharkControl sharkControl = strategy.control(SHARK_CONTROL_TYPE_REFERENCE);
        sysWin = RandCodeUtil
            .random(sharkControl.getLoseRatio() + sharkControl.getWinRatio()) >= sharkControl
                .getLoseRatio();

        count.put(sysWin ? 1 : 0, count.getOrDefault(sysWin ? 1 : 0, 0) + 1);
      }

      Pair<Integer, Long> reward = randomRewardIcon(table, sysWin);
      long sysWinGold = reward.v2;

      long prize = roomPrizePool.getPrize().get();
      prize += sysWinGold;
      roomPrizePool.getPrize().getAndSet(prize);

      return reward.v1;
    }

    return randomIcon(table);
  }

  /**
   * 控制随机奖励图标 .
   * 
   * @param table .
   * @param sysWin . 系统输赢金币
   * @return 中奖图标和系统输赢金币
   */
  private Pair<Integer, Long> randomRewardIcon(SharkTable table, boolean sysWin) {
    SharkSeat banker = table.getBanker();
    Integer randomRewardIcon = null;
    // 系统输赢筹码
    long sysWinChips = 0;

    // 图标倍率
    Map<Integer, Integer> iconRates = table.getIconRates();
    // 玩家合计下注
    long playerTotalBets = table.playerTotalBets();
    // 玩家押注map
    Map<Integer, Long> playerIconBets = table.playerIconBets();
    // 机器人合计下注
    long robotTotalBets = table.robotTotalBets();
    // 机器人押注map
    Map<Integer, Long> robotIconBets = table.robotIconBets();

    if (banker.getPlayerId() == 0) { // 系统坐庄
      if (playerTotalBets == 0) {
        randomRewardIcon = randomIcon(table);
      } else {
        List<Integer> tmpIcons = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15);
        Collections.shuffle(tmpIcons);
        Map<Integer, Long> sysWinMap = new HashMap<Integer, Long>();
        for (Integer icon : tmpIcons) {
          // 中奖筹码
          long tmpReward = sharkMgr.calIconRewardChips(icon, iconRates, playerIconBets);
          long tmpSysWin = playerTotalBets - tmpReward;
          if (tmpSysWin >= 0L) {
            sysWinMap.put(icon, tmpSysWin);
          }
        }

        Map<Integer, Long> calMap = null;
        // 系统赢
        if (sysWin) {
          calMap = sysWinMap;
          if (!calMap.isEmpty()) {
            randomRewardIcon = randIcon(calMap, table);
          } else {
            randomRewardIcon = randomIcon(table);
          }
        } else {
          randomRewardIcon = randomIcon(table);
        }

        long iconRewardChips =
            sharkMgr.calIconRewardChips(randomRewardIcon, iconRates, playerIconBets);
        sysWinChips = playerTotalBets - iconRewardChips;
      }
    } else { // 玩家坐庄
      if (playerTotalBets == 0) {
        randomRewardIcon = randomIcon(table);
      } else {
        List<Integer> tmpIcons = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
        Collections.shuffle(tmpIcons);
        Map<Integer, Long> sysWinMap = new HashMap<Integer, Long>();

        for (Integer icon : tmpIcons) {
          // 中奖筹码
          long tmpReward = sharkMgr.calIconRewardChips(icon, iconRates, robotIconBets);
          long tmpSysWin = tmpReward - robotTotalBets;
          if (tmpSysWin >= 0L) {
            sysWinMap.put(icon, tmpSysWin);
          }
        }

        // 系统赢
        if (sysWin) {
          Map<Integer, Long> calMap = sysWinMap;
          if (!calMap.isEmpty()) {
            randomRewardIcon = randIcon(calMap, table);
          } else {
            randomRewardIcon = randomIcon(table);
          }
        } else {
          randomRewardIcon = randomIcon(table);
        }

        Long iconRewardChips =
            sharkMgr.calIconRewardChips(randomRewardIcon, iconRates, robotIconBets);
        sysWinChips = iconRewardChips - robotTotalBets;
      }
    }

    return new Pair<>(randomRewardIcon,
        sharkMgr.convertGold(table.getRoom().getRoomDomain(), sysWinChips));
  }

  private int randIcon(Map<Integer, Long> calMap, SharkTable table) {
    // 中奖图标id
    int icon = 1;
    int total = 0;
    Map<Integer, SharkIconRateDomain> iconRates =
        iconRateDic.getIconRates().row(table.getIconPlan());
    for (Integer item : calMap.keySet()) {
      SharkIconRateDomain iconDomain = iconRates.get(item);
      total += iconDomain.getProbability();
    }
    long randomPr = RandCodeUtil.random(total);
    long sum = 0;
    for (Integer item : calMap.keySet()) {
      SharkIconRateDomain iconDomain = iconRates.get(item);
      sum += iconDomain.getProbability();
      if (randomPr < sum) {
        icon = item;
        break;
      }
    }
    return icon;
  }

  /**
   * 正常随机图标 .
   * 
   * @param table .
   * @return
   */
  private int randomIcon(SharkTable table) {
    // 中奖图标id
    int icon = 1;

    Map<Integer, SharkIconRateDomain> iconRates =
        iconRateDic.getIconRates().row(table.getIconPlan());
    long randomPr = RandCodeUtil.random(iconRateDic.totalProbability(iconRates));
    long sum = 0;
    for (SharkIconRateDomain iconRateDom : iconRates.values()) {
      sum += iconRateDom.getProbability();
      if (randomPr < sum) {
        icon = iconRateDom.getIcon();
        break;
      }
    }

    return icon;
  }

}
